//自己
class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        //遇难则反:  
        //1. 先求 和正好 == sum-x 的最长数组长度len  (sum是整个数组的和)
        //2. 如果有, n - len就是结果
        int n = nums.size(), len = 0;
        int sum = 0;
        for (int& e : nums)
            sum += e;
        int target = sum-x;
        //特殊情况: 最小操作数是n(x是整个数组的和)时, 需要滑动窗口为空才能求出来
        if (target == 0)
            return n;

        for (int left=0, right=0, sum2=0; right < n; right++)//right越界说明没有满足条件的了, left再移动也没什么意义了
        {
            sum2 += nums[right];//1.入窗口同时sum2+=
            while (left < right && sum2 > target)//2.判断  注意left < right
            {
                sum2 -= nums[left++];//3.出窗口
            }
            //出循环时, 两种情况 ==时更新len后继续;  <时直接继续进窗口
            if (sum2 == target)//4.更新
            {
                len = max(len, right-left+1);
            }
        }
        return len==0 ? -1 : n-len;
    }
};


//答案
class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        //遇难则反:  
        //1. 先求 和正好 == sum-x 的最长数组长度len  (sum是整个数组的和)
        //2. 如果有, n - len就是结果
        int n = nums.size(), sum = 0, len = -1;
        for (int& e : nums) sum += e;
        int target = sum-x;
        //细节问题
        if (target < 0) return -1; //<0 说明x比整个数组的和都大, 那一定不满足, 直接返回-1

        for (int left=0, right=0, sum2=0; right < n; right++)//right越界说明没有满足条件的了, left再移动也没什么意义了
        {
            sum2 += nums[right];//1.入窗口同时sum2+= (sum2是数组长度)
            while (sum2 > target)//2.判断
                sum2 -= nums[left++];//3.出窗口
            //出循环时, 两种情况 ==时更新len后继续;  <时直接继续进窗口
            if (sum2 == target)//4.更新         target==0的情况也适用
                len = max(len, right-left+1);
        }
        return len==-1 ? -1 : n-len;
    }
};
//时间 O(N)
//空间 O(1)